﻿using Aop.Api.Request;
using Aop.Api.Response;
using Aop.Api;
using AutoMapper;
using CodeFirst;
using Common;
using IRepository;
using IService;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Model;
using ModelDto;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
using System.Reflection;
using Aop.Api.Domain;
using Microsoft.EntityFrameworkCore.Storage;

namespace Service
{
    [Service]
    public class CeshiService : ICeshiService
    {
        private readonly IBaseRepository<PurchaseOrder> _baseRepository;
        private readonly IMapper _mapper;
        private readonly IOptions<SystemAppSettings> _options;
        private readonly IRedisHelper _redisHelper;
        private readonly MyDbContext _context;
        private readonly Ilog4netHelper _log4netHelper;
        public CeshiService(IBaseRepository<PurchaseOrder> baseRepository,
            IMapper mapper,
            IOptions<SystemAppSettings> options,
            IRedisHelper redisHelper,
            MyDbContext context,
            Ilog4netHelper log4netHelper
            )
        {
            _baseRepository = baseRepository;
            _mapper = mapper;
            _options = options;
            _redisHelper = redisHelper;
            _context = context;
            _log4netHelper = log4netHelper;
        }

        public async Task<List<PurchaseOrderDto>> Excel()
        {
            var excelList = await _baseRepository.GetAll().ToListAsync();
            List<PurchaseOrderDto> data = _mapper.Map<List<PurchaseOrderDto>>(excelList);
            Type myType = typeof(PurchaseOrderDto);
            FieldInfo[] fields = myType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (FieldInfo field in fields)
            {
                Console.WriteLine(field.Name);
            }
            return null;
        }
        public class Order
        {
            public int OrderId { get; set; }
            public string CustomerName { get; set; }
            public DateTime OrderDate { get; set; }
            public virtual ICollection<OrderItem> OrderItems { get; set; }
        }

        public class OrderItem
        {
            public int OrderItemId { get; set; }
            public int OrderId { get; set; }
            public string ProductName { get; set; }
            public decimal Price { get; set; }
            public int Quantity { get; set; }
            public virtual Order Order { get; set; }
        }
        public async Task<PurchaseOrderDto> GetPurchase(string purchaseId)
        {
            // 创建一个需要更新的订单对象
            var updatedOrder = new Order
            {
                OrderId = 1, // 假设这是数据库中已存在的订单ID
                CustomerName = "张三",
                OrderDate = DateTime.Now,
                OrderItems = new List<OrderItem>
    {
        new OrderItem { OrderItemId = 1, ProductName = "产品A", Price = 100.00m, Quantity = 2 },
        new OrderItem { OrderItemId = 2, ProductName = "产品B", Price = 200.00m, Quantity = 1 },
        new OrderItem { OrderItemId = 3, ProductName = "产品C", Price = 150.00m, Quantity = 3 } // 新增的订单项
    }
            };

            // 调用 UpdateWithChildren 方法更新订单及其订单项
            _baseRepository.UpdateWithChildren<Order, OrderItem, int, int>(
                updatedPrincipal: updatedOrder,
                order => order.OrderItems,
                orderItem => orderItem.OrderItemId,
                order => order.OrderId
            );
            ////测试读取配置文件
            //string a = _options.Value.ConnectStrWrite;

            ////测试redis是否注入成功
            //_redisHelper.SetValue("1", "wsnd");

            //// 测试日志
            //_log4netHelper.SetLoggerName(LogNameEnum.InfoLog);
            //_log4netHelper.Info("测试");

            //不同DBContext共享同一个事务
            //using (var transaction = _context.Database.BeginTransaction())
            //{
            //    var purchaseOrder = await _baseRepository.FirstOrDefaultAsync(f => f.Id == purchaseId);
            //    // 使用相同的数据库连接和事务
            //    _baseRepository.GetDbContext().Database.UseTransaction(transaction.GetDbTransaction()); ;
            //    PurchaseOrderDto data = _mapper.Map<PurchaseOrderDto>(purchaseOrder);
            //    purchaseOrder.Order = "123123";
            //    await _baseRepository.UpdateAsync(purchaseOrder);
            //}

            //开启事务
            var transaction = _baseRepository.BeginTransaction;
            try
            {
                var purchaseOrder = await _baseRepository.FirstOrDefaultAsync(f => f.Id == purchaseId);
                PurchaseOrderDto data = _mapper.Map<PurchaseOrderDto>(purchaseOrder);
                purchaseOrder.Order = "123123";
                await _baseRepository.UpdateAsync(purchaseOrder);
                _baseRepository.Commit();
                return data;
            }
            catch (Exception)
            {
                _baseRepository.Rollback();
                _baseRepository.Dispose();
                return null;
            }

        }
        
        
        
        
        #region 第三方支付接口
        //第三方微信对接用法，参数全是乱填，需要根据特定东西来传
        public async Task WechatApiAsync()
        {
            WechatTenpayClient wechatTenpayClient = new WechatTenpayClient(new WechatTenpayClientOptions()
            {
                MerchantId = DateTimeOffset.Now.ToUnixTimeSeconds().ToString(),
                MerchantCertificateSerialNumber = Guid.NewGuid().ToString("N"),
                MerchantCertificatePrivateKey = "",
                MerchantV3Secret = Guid.NewGuid().ToString("N"),
                PlatformCertificateManager = null,
                AutoEncryptRequestSensitiveProperty = true
            });
            var request = new CreateApplyForSubjectApplymentRequest()
            {
                Contact = new CreateApplyForSubjectApplymentRequest.Types.Contact()
                {
                    ContactName = "",
                    IdNumber = ""
                },
                Identification = new CreateApplyForSubjectApplymentRequest.Types.Identification()
                {
                    IdName = "",
                    IdNumber = "",
                    IdAddress = ""
                },
                UBOList = new List<CreateApplyForSubjectApplymentRequest.Types.UBO>()
                    {
                        new CreateApplyForSubjectApplymentRequest.Types.UBO()
                        {
                            IdName = "",
                            IdNumber = "",
                            IdAddress = ""
                        }
                }
            };
            CreateApplyForSubjectApplymentResponse a = await wechatTenpayClient.ExecuteCreateApplyForSubjectApplymentAsync(request);
        }

        //支付宝官方SDK，各接口请看 https://opendocs.alipay.com/mini/api?pathHash=5b4d0c83 文档
        public void AliPayApi()
        {
            IAopClient client = new DefaultAopClient("https://openapi.alipay.com/gateway.do", "APPID", "APP_PRIVATE_KEY", "json", "1.0", "RSA2", "ALIPAY_PUBLIC_KEY", "CHARSET", false);
            //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称如：alipay.open.public.template.message.industry.modify 
            AlipayOpenPublicTemplateMessageIndustryModifyRequest request = new AlipayOpenPublicTemplateMessageIndustryModifyRequest();
            //SDK已经封装掉了公共参数，这里只需要传入业务参数
            //此次只是参数展示，未进行字符串转义，实际情况下请转义
            request.BizContent = "{" +
            "    \"primary_industry_name\":\"IT科技/IT软件与服务\"," +
            "    \"primary_industry_code\":\"10001/20102\"," +
            "    \"secondary_industry_code\":\"10001/20102\"," +
            "    \"secondary_industry_name\":\"IT科技/IT软件与服务\"" +
            "  }";
            AlipayOpenPublicTemplateMessageIndustryModifyResponse response = client.Execute(request);
            if (!response.IsError)
            {
                //调用成功
            }
            else
            {
                Console.WriteLine("调用失败");
            }
            //调用成功，则处理业务逻辑
        }

        #endregion

    }
}
